//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension DAX {
    // MARK: Enums

    public enum ChangeType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case immediate = "IMMEDIATE"
        case requiresReboot = "REQUIRES_REBOOT"
        public var description: String { return self.rawValue }
    }

    public enum ClusterEndpointEncryptionType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case none = "NONE"
        case tls = "TLS"
        public var description: String { return self.rawValue }
    }

    public enum IsModifiable: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `false` = "FALSE"
        case `true` = "TRUE"
        case conditional = "CONDITIONAL"
        public var description: String { return self.rawValue }
    }

    public enum ParameterType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `default` = "DEFAULT"
        case nodeTypeSpecific = "NODE_TYPE_SPECIFIC"
        public var description: String { return self.rawValue }
    }

    public enum SSEStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case disabling = "DISABLING"
        case enabled = "ENABLED"
        case enabling = "ENABLING"
        public var description: String { return self.rawValue }
    }

    public enum SourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cluster = "CLUSTER"
        case parameterGroup = "PARAMETER_GROUP"
        case subnetGroup = "SUBNET_GROUP"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct Cluster: AWSDecodableShape {
        /// The number of nodes in the cluster that are active (i.e., capable of serving requests).
        public let activeNodes: Int?
        /// The Amazon Resource Name (ARN) that uniquely identifies the cluster.
        public let clusterArn: String?
        /// The endpoint for this DAX cluster, consisting of a DNS name, a port number, and a URL. Applications should use the URL to configure the DAX client to find their cluster.
        public let clusterDiscoveryEndpoint: Endpoint?
        /// The type of encryption supported by the cluster's endpoint. Values are:    NONE for no encryption  TLS for Transport Layer Security
        public let clusterEndpointEncryptionType: ClusterEndpointEncryptionType?
        /// The name of the DAX cluster.
        public let clusterName: String?
        /// The description of the cluster.
        public let description: String?
        /// A valid Amazon Resource Name (ARN) that identifies an IAM role. At runtime, DAX will assume this role and use the role's permissions to access DynamoDB on your behalf.
        public let iamRoleArn: String?
        /// A list of nodes to be removed from the cluster.
        public let nodeIdsToRemove: [String]?
        /// A list of nodes that are currently in the cluster.
        public let nodes: [Node]?
        /// The node type for the nodes in the cluster. (All nodes in a DAX cluster are of the same type.)
        public let nodeType: String?
        /// Describes a notification topic and its status. Notification topics are used for publishing DAX events to subscribers using Amazon Simple Notification Service (SNS).
        public let notificationConfiguration: NotificationConfiguration?
        /// The parameter group being used by nodes in the cluster.
        public let parameterGroup: ParameterGroupStatus?
        /// A range of time when maintenance of DAX cluster software will be performed. For example: sun:01:00-sun:09:00. Cluster maintenance normally takes less than 30 minutes, and is performed automatically within the maintenance window.
        public let preferredMaintenanceWindow: String?
        /// A list of security groups, and the status of each, for the nodes in the cluster.
        public let securityGroups: [SecurityGroupMembership]?
        /// The description of the server-side encryption status on the specified DAX cluster.
        public let sseDescription: SSEDescription?
        /// The current status of the cluster.
        public let status: String?
        /// The subnet group where the DAX cluster is running.
        public let subnetGroup: String?
        /// The total number of nodes in the cluster.
        public let totalNodes: Int?

        @inlinable
        public init(activeNodes: Int? = nil, clusterArn: String? = nil, clusterDiscoveryEndpoint: Endpoint? = nil, clusterEndpointEncryptionType: ClusterEndpointEncryptionType? = nil, clusterName: String? = nil, description: String? = nil, iamRoleArn: String? = nil, nodeIdsToRemove: [String]? = nil, nodes: [Node]? = nil, nodeType: String? = nil, notificationConfiguration: NotificationConfiguration? = nil, parameterGroup: ParameterGroupStatus? = nil, preferredMaintenanceWindow: String? = nil, securityGroups: [SecurityGroupMembership]? = nil, sseDescription: SSEDescription? = nil, status: String? = nil, subnetGroup: String? = nil, totalNodes: Int? = nil) {
            self.activeNodes = activeNodes
            self.clusterArn = clusterArn
            self.clusterDiscoveryEndpoint = clusterDiscoveryEndpoint
            self.clusterEndpointEncryptionType = clusterEndpointEncryptionType
            self.clusterName = clusterName
            self.description = description
            self.iamRoleArn = iamRoleArn
            self.nodeIdsToRemove = nodeIdsToRemove
            self.nodes = nodes
            self.nodeType = nodeType
            self.notificationConfiguration = notificationConfiguration
            self.parameterGroup = parameterGroup
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.securityGroups = securityGroups
            self.sseDescription = sseDescription
            self.status = status
            self.subnetGroup = subnetGroup
            self.totalNodes = totalNodes
        }

        private enum CodingKeys: String, CodingKey {
            case activeNodes = "ActiveNodes"
            case clusterArn = "ClusterArn"
            case clusterDiscoveryEndpoint = "ClusterDiscoveryEndpoint"
            case clusterEndpointEncryptionType = "ClusterEndpointEncryptionType"
            case clusterName = "ClusterName"
            case description = "Description"
            case iamRoleArn = "IamRoleArn"
            case nodeIdsToRemove = "NodeIdsToRemove"
            case nodes = "Nodes"
            case nodeType = "NodeType"
            case notificationConfiguration = "NotificationConfiguration"
            case parameterGroup = "ParameterGroup"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case securityGroups = "SecurityGroups"
            case sseDescription = "SSEDescription"
            case status = "Status"
            case subnetGroup = "SubnetGroup"
            case totalNodes = "TotalNodes"
        }
    }

    public struct CreateClusterRequest: AWSEncodableShape {
        /// The Availability Zones (AZs) in which the cluster nodes will reside after the cluster has been created or updated. If provided, the length of this list must equal the ReplicationFactor parameter. If you omit this parameter, DAX will spread the nodes across Availability Zones for the highest availability.
        public let availabilityZones: [String]?
        /// The type of encryption the cluster's endpoint should support. Values are:    NONE for no encryption    TLS for Transport Layer Security
        public let clusterEndpointEncryptionType: ClusterEndpointEncryptionType?
        /// The cluster identifier. This parameter is stored as a lowercase string.  Constraints:    A name must contain from 1 to 20 alphanumeric characters or hyphens.   The first character must be a letter.   A name cannot end with a hyphen or contain two consecutive hyphens.
        public let clusterName: String
        /// A description of the cluster.
        public let description: String?
        /// A valid Amazon Resource Name (ARN) that identifies an IAM role. At runtime, DAX will assume this role and use the role's permissions to access DynamoDB on your behalf.
        public let iamRoleArn: String
        /// The compute and memory capacity of the nodes in the cluster.
        public let nodeType: String
        /// The Amazon Resource Name (ARN) of the Amazon SNS topic to which notifications will be sent.  The Amazon SNS topic owner must be same as the DAX cluster owner.
        public let notificationTopicArn: String?
        /// The parameter group to be associated with the DAX cluster.
        public let parameterGroupName: String?
        /// Specifies the weekly time range during which maintenance on the DAX cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:    sun     mon     tue     wed     thu     fri     sat    Example: sun:05:00-sun:09:00   If you don't specify a preferred maintenance window when you create or modify a cache cluster, DAX assigns a 60-minute maintenance window on a randomly selected day of the week.
        public let preferredMaintenanceWindow: String?
        /// The number of nodes in the DAX cluster. A replication factor of 1 will create a single-node cluster, without any read replicas. For additional fault tolerance, you can create a multiple node cluster with one or more read replicas. To do this, set ReplicationFactor to a number between 3 (one primary and two read replicas) and 10 (one primary and nine read replicas).  If the AvailabilityZones parameter is provided, its length must equal the ReplicationFactor.  AWS recommends that you have at least two read replicas per cluster.
        public let replicationFactor: Int
        /// A list of security group IDs to be assigned to each node in the DAX cluster. (Each of the  security group ID is system-generated.) If this parameter is not specified, DAX assigns the default VPC security group to each node.
        public let securityGroupIds: [String]?
        /// Represents the settings used to enable server-side encryption on the cluster.
        public let sseSpecification: SSESpecification?
        /// The name of the subnet group to be used for the replication group.  DAX clusters can only run in an Amazon VPC environment. All of the subnets that you specify in a subnet group must exist in the same VPC.
        public let subnetGroupName: String?
        /// A set of tags to associate with the DAX cluster.
        public let tags: [Tag]?

        @inlinable
        public init(availabilityZones: [String]? = nil, clusterEndpointEncryptionType: ClusterEndpointEncryptionType? = nil, clusterName: String, description: String? = nil, iamRoleArn: String, nodeType: String, notificationTopicArn: String? = nil, parameterGroupName: String? = nil, preferredMaintenanceWindow: String? = nil, replicationFactor: Int = 0, securityGroupIds: [String]? = nil, sseSpecification: SSESpecification? = nil, subnetGroupName: String? = nil, tags: [Tag]? = nil) {
            self.availabilityZones = availabilityZones
            self.clusterEndpointEncryptionType = clusterEndpointEncryptionType
            self.clusterName = clusterName
            self.description = description
            self.iamRoleArn = iamRoleArn
            self.nodeType = nodeType
            self.notificationTopicArn = notificationTopicArn
            self.parameterGroupName = parameterGroupName
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.replicationFactor = replicationFactor
            self.securityGroupIds = securityGroupIds
            self.sseSpecification = sseSpecification
            self.subnetGroupName = subnetGroupName
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case clusterEndpointEncryptionType = "ClusterEndpointEncryptionType"
            case clusterName = "ClusterName"
            case description = "Description"
            case iamRoleArn = "IamRoleArn"
            case nodeType = "NodeType"
            case notificationTopicArn = "NotificationTopicArn"
            case parameterGroupName = "ParameterGroupName"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case replicationFactor = "ReplicationFactor"
            case securityGroupIds = "SecurityGroupIds"
            case sseSpecification = "SSESpecification"
            case subnetGroupName = "SubnetGroupName"
            case tags = "Tags"
        }
    }

    public struct CreateClusterResponse: AWSDecodableShape {
        /// A description of the DAX cluster that you have created.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct CreateParameterGroupRequest: AWSEncodableShape {
        /// A description of the parameter group.
        public let description: String?
        /// The name of the parameter group to apply to all of the clusters in this replication group.
        public let parameterGroupName: String

        @inlinable
        public init(description: String? = nil, parameterGroupName: String) {
            self.description = description
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct CreateParameterGroupResponse: AWSDecodableShape {
        /// Represents the output of a CreateParameterGroup action.
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct CreateSubnetGroupRequest: AWSEncodableShape {
        /// A description for the subnet group
        public let description: String?
        /// A name for the subnet group. This value is stored as a lowercase string.
        public let subnetGroupName: String
        /// A list of VPC subnet IDs for the subnet group.
        public let subnetIds: [String]

        @inlinable
        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String]) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
        }
    }

    public struct CreateSubnetGroupResponse: AWSDecodableShape {
        /// Represents the output of a CreateSubnetGroup operation.
        public let subnetGroup: SubnetGroup?

        @inlinable
        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct DecreaseReplicationFactorRequest: AWSEncodableShape {
        /// The Availability Zone(s) from which to remove nodes.
        public let availabilityZones: [String]?
        /// The name of the DAX cluster from which you want to remove nodes.
        public let clusterName: String
        /// The new number of nodes for the DAX cluster.
        public let newReplicationFactor: Int
        /// The unique identifiers of the nodes to be removed from the cluster.
        public let nodeIdsToRemove: [String]?

        @inlinable
        public init(availabilityZones: [String]? = nil, clusterName: String, newReplicationFactor: Int = 0, nodeIdsToRemove: [String]? = nil) {
            self.availabilityZones = availabilityZones
            self.clusterName = clusterName
            self.newReplicationFactor = newReplicationFactor
            self.nodeIdsToRemove = nodeIdsToRemove
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case clusterName = "ClusterName"
            case newReplicationFactor = "NewReplicationFactor"
            case nodeIdsToRemove = "NodeIdsToRemove"
        }
    }

    public struct DecreaseReplicationFactorResponse: AWSDecodableShape {
        /// A description of the DAX cluster, after you have decreased its replication factor.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct DeleteClusterRequest: AWSEncodableShape {
        /// The name of the cluster to be deleted.
        public let clusterName: String

        @inlinable
        public init(clusterName: String) {
            self.clusterName = clusterName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
        }
    }

    public struct DeleteClusterResponse: AWSDecodableShape {
        /// A description of the DAX cluster that is being deleted.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct DeleteParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group to delete.
        public let parameterGroupName: String

        @inlinable
        public init(parameterGroupName: String) {
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DeleteParameterGroupResponse: AWSDecodableShape {
        /// A user-specified message for this action (i.e., a reason for deleting the parameter group).
        public let deletionMessage: String?

        @inlinable
        public init(deletionMessage: String? = nil) {
            self.deletionMessage = deletionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case deletionMessage = "DeletionMessage"
        }
    }

    public struct DeleteSubnetGroupRequest: AWSEncodableShape {
        /// The name of the subnet group to delete.
        public let subnetGroupName: String

        @inlinable
        public init(subnetGroupName: String) {
            self.subnetGroupName = subnetGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroupName = "SubnetGroupName"
        }
    }

    public struct DeleteSubnetGroupResponse: AWSDecodableShape {
        /// A user-specified message for this action (i.e., a reason for deleting the subnet group).
        public let deletionMessage: String?

        @inlinable
        public init(deletionMessage: String? = nil) {
            self.deletionMessage = deletionMessage
        }

        private enum CodingKeys: String, CodingKey {
            case deletionMessage = "DeletionMessage"
        }
    }

    public struct DescribeClustersRequest: AWSEncodableShape {
        /// The names of the DAX clusters being described.
        public let clusterNames: [String]?
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?

        @inlinable
        public init(clusterNames: [String]? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.clusterNames = clusterNames
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusterNames = "ClusterNames"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeClustersResponse: AWSDecodableShape {
        /// The descriptions of your DAX clusters, in response to a DescribeClusters request.
        public let clusters: [Cluster]?
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?

        @inlinable
        public init(clusters: [Cluster]? = nil, nextToken: String? = nil) {
            self.clusters = clusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusters = "Clusters"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeDefaultParametersRequest: AWSEncodableShape {
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeDefaultParametersResponse: AWSDecodableShape {
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?
        /// A list of parameters.  Each element in the list represents one parameter.
        public let parameters: [Parameter]?

        @inlinable
        public init(nextToken: String? = nil, parameters: [Parameter]? = nil) {
            self.nextToken = nextToken
            self.parameters = parameters
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameters = "Parameters"
        }
    }

    public struct DescribeEventsRequest: AWSEncodableShape {
        /// The number of minutes' worth of events to retrieve.
        public let duration: Int?
        /// The end of the time interval for which to retrieve events, specified in ISO 8601 format.
        public let endTime: Date?
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?
        /// The identifier of the event source for which events will be returned. If not specified, then all sources are included in the response.
        public let sourceName: String?
        /// The event source to retrieve events for. If no value is specified, all events are returned.
        public let sourceType: SourceType?
        /// The beginning of the time interval to retrieve events for, specified in ISO 8601 format.
        public let startTime: Date?

        @inlinable
        public init(duration: Int? = nil, endTime: Date? = nil, maxResults: Int? = nil, nextToken: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil, startTime: Date? = nil) {
            self.duration = duration
            self.endTime = endTime
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.sourceName = sourceName
            self.sourceType = sourceType
            self.startTime = startTime
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case endTime = "EndTime"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
            case startTime = "StartTime"
        }
    }

    public struct DescribeEventsResponse: AWSDecodableShape {
        /// An array of events.  Each element in the array represents one event.
        public let events: [Event]?
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?

        @inlinable
        public init(events: [Event]? = nil, nextToken: String? = nil) {
            self.events = events
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case events = "Events"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeParameterGroupsRequest: AWSEncodableShape {
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?
        /// The names of the parameter groups.
        public let parameterGroupNames: [String]?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupNames: [String]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupNames = parameterGroupNames
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupNames = "ParameterGroupNames"
        }
    }

    public struct DescribeParameterGroupsResponse: AWSDecodableShape {
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?
        /// An array of parameter groups.  Each element in the array represents one parameter group.
        public let parameterGroups: [ParameterGroup]?

        @inlinable
        public init(nextToken: String? = nil, parameterGroups: [ParameterGroup]? = nil) {
            self.nextToken = nextToken
            self.parameterGroups = parameterGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameterGroups = "ParameterGroups"
        }
    }

    public struct DescribeParametersRequest: AWSEncodableShape {
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?
        /// The name of the parameter group.
        public let parameterGroupName: String
        /// How the parameter is defined. For example, system denotes a system-defined parameter.
        public let source: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupName: String, source: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupName = parameterGroupName
            self.source = source
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupName = "ParameterGroupName"
            case source = "Source"
        }
    }

    public struct DescribeParametersResponse: AWSDecodableShape {
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?
        /// A list of parameters within a parameter group.  Each element in the list represents one parameter.
        public let parameters: [Parameter]?

        @inlinable
        public init(nextToken: String? = nil, parameters: [Parameter]? = nil) {
            self.nextToken = nextToken
            self.parameters = parameters
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameters = "Parameters"
        }
    }

    public struct DescribeSubnetGroupsRequest: AWSEncodableShape {
        /// The maximum number of results to include in the response. If more results exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved. The value for MaxResults must be between 20 and 100.
        public let maxResults: Int?
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token, up to the value specified by MaxResults.
        public let nextToken: String?
        /// The name of the subnet group.
        public let subnetGroupNames: [String]?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, subnetGroupNames: [String]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.subnetGroupNames = subnetGroupNames
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case subnetGroupNames = "SubnetGroupNames"
        }
    }

    public struct DescribeSubnetGroupsResponse: AWSDecodableShape {
        /// Provides an identifier to allow retrieval of paginated results.
        public let nextToken: String?
        /// An array of subnet groups.  Each element in the array represents a single subnet group.
        public let subnetGroups: [SubnetGroup]?

        @inlinable
        public init(nextToken: String? = nil, subnetGroups: [SubnetGroup]? = nil) {
            self.nextToken = nextToken
            self.subnetGroups = subnetGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case subnetGroups = "SubnetGroups"
        }
    }

    public struct Endpoint: AWSDecodableShape {
        /// The DNS hostname of the endpoint.
        public let address: String?
        /// The port number that applications should use to connect to the endpoint.
        public let port: Int?
        /// The URL that applications should use to connect to the endpoint. The default ports are 8111 for the "dax" protocol and 9111 for the "daxs" protocol.
        public let url: String?

        @inlinable
        public init(address: String? = nil, port: Int? = nil, url: String? = nil) {
            self.address = address
            self.port = port
            self.url = url
        }

        private enum CodingKeys: String, CodingKey {
            case address = "Address"
            case port = "Port"
            case url = "URL"
        }
    }

    public struct Event: AWSDecodableShape {
        /// The date and time when the event occurred.
        public let date: Date?
        /// A user-defined message associated with the event.
        public let message: String?
        /// The source of the event. For example, if the event occurred at the node level, the source would be the node ID.
        public let sourceName: String?
        /// Specifies the origin of this event - a cluster, a parameter group, a node ID, etc.
        public let sourceType: SourceType?

        @inlinable
        public init(date: Date? = nil, message: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil) {
            self.date = date
            self.message = message
            self.sourceName = sourceName
            self.sourceType = sourceType
        }

        private enum CodingKeys: String, CodingKey {
            case date = "Date"
            case message = "Message"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
        }
    }

    public struct IncreaseReplicationFactorRequest: AWSEncodableShape {
        /// The Availability Zones (AZs) in which the cluster nodes will be created. All nodes belonging to the cluster are placed in these Availability Zones. Use this parameter if you want to distribute the nodes across multiple AZs.
        public let availabilityZones: [String]?
        /// The name of the DAX cluster that will receive additional nodes.
        public let clusterName: String
        /// The new number of nodes for the DAX cluster.
        public let newReplicationFactor: Int

        @inlinable
        public init(availabilityZones: [String]? = nil, clusterName: String, newReplicationFactor: Int = 0) {
            self.availabilityZones = availabilityZones
            self.clusterName = clusterName
            self.newReplicationFactor = newReplicationFactor
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case clusterName = "ClusterName"
            case newReplicationFactor = "NewReplicationFactor"
        }
    }

    public struct IncreaseReplicationFactorResponse: AWSDecodableShape {
        /// A description of the DAX cluster. with its new replication factor.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct ListTagsRequest: AWSEncodableShape {
        /// An optional token returned from a prior request. Use this token for pagination of results from this action. If this parameter is specified, the response includes only results beyond the token.
        public let nextToken: String?
        /// The name of the DAX resource to which the tags belong.
        public let resourceName: String

        @inlinable
        public init(nextToken: String? = nil, resourceName: String) {
            self.nextToken = nextToken
            self.resourceName = resourceName
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case resourceName = "ResourceName"
        }
    }

    public struct ListTagsResponse: AWSDecodableShape {
        /// If this value is present, there are additional results to be displayed.  To retrieve them, call  ListTags again, with NextToken set to this value.
        public let nextToken: String?
        /// A list of tags currently associated with the DAX cluster.
        public let tags: [Tag]?

        @inlinable
        public init(nextToken: String? = nil, tags: [Tag]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct Node: AWSDecodableShape {
        /// The Availability Zone (AZ) in which the node has been deployed.
        public let availabilityZone: String?
        /// The endpoint for the node, consisting of a DNS name and a port number. Client applications can connect directly to a node endpoint, if desired (as an alternative to allowing DAX client software to intelligently route requests and responses to nodes in the DAX cluster.
        public let endpoint: Endpoint?
        /// The date and time (in UNIX epoch format) when the node was launched.
        public let nodeCreateTime: Date?
        /// A system-generated identifier for the node.
        public let nodeId: String?
        /// The current status of the node. For example: available.
        public let nodeStatus: String?
        /// The status of the parameter group associated with this node. For example, in-sync.
        public let parameterGroupStatus: String?

        @inlinable
        public init(availabilityZone: String? = nil, endpoint: Endpoint? = nil, nodeCreateTime: Date? = nil, nodeId: String? = nil, nodeStatus: String? = nil, parameterGroupStatus: String? = nil) {
            self.availabilityZone = availabilityZone
            self.endpoint = endpoint
            self.nodeCreateTime = nodeCreateTime
            self.nodeId = nodeId
            self.nodeStatus = nodeStatus
            self.parameterGroupStatus = parameterGroupStatus
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case endpoint = "Endpoint"
            case nodeCreateTime = "NodeCreateTime"
            case nodeId = "NodeId"
            case nodeStatus = "NodeStatus"
            case parameterGroupStatus = "ParameterGroupStatus"
        }
    }

    public struct NodeTypeSpecificValue: AWSDecodableShape {
        /// A node type to which the parameter value applies.
        public let nodeType: String?
        /// The parameter value for this node type.
        public let value: String?

        @inlinable
        public init(nodeType: String? = nil, value: String? = nil) {
            self.nodeType = nodeType
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case nodeType = "NodeType"
            case value = "Value"
        }
    }

    public struct NotificationConfiguration: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the topic.
        public let topicArn: String?
        /// The current state of the topic. A value of “active” means that notifications will be sent to the topic. A value of “inactive” means that notifications will not be sent to the topic.
        public let topicStatus: String?

        @inlinable
        public init(topicArn: String? = nil, topicStatus: String? = nil) {
            self.topicArn = topicArn
            self.topicStatus = topicStatus
        }

        private enum CodingKeys: String, CodingKey {
            case topicArn = "TopicArn"
            case topicStatus = "TopicStatus"
        }
    }

    public struct Parameter: AWSDecodableShape {
        /// A range of values within which the parameter can be set.
        public let allowedValues: String?
        /// The conditions under which changes to this parameter can be applied. For example, requires-reboot indicates that a new value for this parameter will only take effect if a node is rebooted.
        public let changeType: ChangeType?
        /// The data type of the parameter. For example, integer:
        public let dataType: String?
        /// A description of the parameter
        public let description: String?
        /// Whether the customer is allowed to modify the parameter.
        public let isModifiable: IsModifiable?
        /// A list of node types, and specific parameter values for each node.
        public let nodeTypeSpecificValues: [NodeTypeSpecificValue]?
        /// The name of the parameter.
        public let parameterName: String?
        /// Determines whether the parameter can be applied to any nodes, or only nodes of a particular type.
        public let parameterType: ParameterType?
        /// The value for the parameter.
        public let parameterValue: String?
        /// How the parameter is defined. For example, system denotes a system-defined parameter.
        public let source: String?

        @inlinable
        public init(allowedValues: String? = nil, changeType: ChangeType? = nil, dataType: String? = nil, description: String? = nil, isModifiable: IsModifiable? = nil, nodeTypeSpecificValues: [NodeTypeSpecificValue]? = nil, parameterName: String? = nil, parameterType: ParameterType? = nil, parameterValue: String? = nil, source: String? = nil) {
            self.allowedValues = allowedValues
            self.changeType = changeType
            self.dataType = dataType
            self.description = description
            self.isModifiable = isModifiable
            self.nodeTypeSpecificValues = nodeTypeSpecificValues
            self.parameterName = parameterName
            self.parameterType = parameterType
            self.parameterValue = parameterValue
            self.source = source
        }

        private enum CodingKeys: String, CodingKey {
            case allowedValues = "AllowedValues"
            case changeType = "ChangeType"
            case dataType = "DataType"
            case description = "Description"
            case isModifiable = "IsModifiable"
            case nodeTypeSpecificValues = "NodeTypeSpecificValues"
            case parameterName = "ParameterName"
            case parameterType = "ParameterType"
            case parameterValue = "ParameterValue"
            case source = "Source"
        }
    }

    public struct ParameterGroup: AWSDecodableShape {
        /// A description of the parameter group.
        public let description: String?
        /// The name of the parameter group.
        public let parameterGroupName: String?

        @inlinable
        public init(description: String? = nil, parameterGroupName: String? = nil) {
            self.description = description
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct ParameterGroupStatus: AWSDecodableShape {
        /// The node IDs of one or more nodes to be rebooted.
        public let nodeIdsToReboot: [String]?
        /// The status of parameter updates.
        public let parameterApplyStatus: String?
        /// The name of the parameter group.
        public let parameterGroupName: String?

        @inlinable
        public init(nodeIdsToReboot: [String]? = nil, parameterApplyStatus: String? = nil, parameterGroupName: String? = nil) {
            self.nodeIdsToReboot = nodeIdsToReboot
            self.parameterApplyStatus = parameterApplyStatus
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case nodeIdsToReboot = "NodeIdsToReboot"
            case parameterApplyStatus = "ParameterApplyStatus"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct ParameterNameValue: AWSEncodableShape {
        /// The name of the parameter.
        public let parameterName: String?
        /// The value of the parameter.
        public let parameterValue: String?

        @inlinable
        public init(parameterName: String? = nil, parameterValue: String? = nil) {
            self.parameterName = parameterName
            self.parameterValue = parameterValue
        }

        private enum CodingKeys: String, CodingKey {
            case parameterName = "ParameterName"
            case parameterValue = "ParameterValue"
        }
    }

    public struct RebootNodeRequest: AWSEncodableShape {
        /// The name of the DAX cluster containing the node to be rebooted.
        public let clusterName: String
        /// The system-assigned ID of the node to be rebooted.
        public let nodeId: String

        @inlinable
        public init(clusterName: String, nodeId: String) {
            self.clusterName = clusterName
            self.nodeId = nodeId
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case nodeId = "NodeId"
        }
    }

    public struct RebootNodeResponse: AWSDecodableShape {
        /// A description of the DAX cluster after a node has been rebooted.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct SSEDescription: AWSDecodableShape {
        /// The current state of server-side encryption:    ENABLING - Server-side encryption is being enabled.    ENABLED - Server-side encryption is enabled.    DISABLING - Server-side encryption is being disabled.    DISABLED - Server-side encryption is disabled.
        public let status: SSEStatus?

        @inlinable
        public init(status: SSEStatus? = nil) {
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case status = "Status"
        }
    }

    public struct SSESpecification: AWSEncodableShape {
        /// Indicates whether server-side encryption is enabled (true) or disabled (false) on the cluster.
        public let enabled: Bool

        @inlinable
        public init(enabled: Bool) {
            self.enabled = enabled
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "Enabled"
        }
    }

    public struct SecurityGroupMembership: AWSDecodableShape {
        /// The unique ID for this security group.
        public let securityGroupIdentifier: String?
        /// The status of this security group.
        public let status: String?

        @inlinable
        public init(securityGroupIdentifier: String? = nil, status: String? = nil) {
            self.securityGroupIdentifier = securityGroupIdentifier
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupIdentifier = "SecurityGroupIdentifier"
            case status = "Status"
        }
    }

    public struct Subnet: AWSDecodableShape {
        /// The Availability Zone (AZ) for the subnet.
        public let subnetAvailabilityZone: String?
        /// The system-assigned identifier for the subnet.
        public let subnetIdentifier: String?

        @inlinable
        public init(subnetAvailabilityZone: String? = nil, subnetIdentifier: String? = nil) {
            self.subnetAvailabilityZone = subnetAvailabilityZone
            self.subnetIdentifier = subnetIdentifier
        }

        private enum CodingKeys: String, CodingKey {
            case subnetAvailabilityZone = "SubnetAvailabilityZone"
            case subnetIdentifier = "SubnetIdentifier"
        }
    }

    public struct SubnetGroup: AWSDecodableShape {
        /// The description of the subnet group.
        public let description: String?
        /// The name of the subnet group.
        public let subnetGroupName: String?
        /// A list of subnets associated with the subnet group.
        public let subnets: [Subnet]?
        /// The Amazon Virtual Private Cloud identifier (VPC ID) of the subnet group.
        public let vpcId: String?

        @inlinable
        public init(description: String? = nil, subnetGroupName: String? = nil, subnets: [Subnet]? = nil, vpcId: String? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnets = subnets
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnets = "Subnets"
            case vpcId = "VpcId"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key for the tag.  Tag keys are case sensitive. Every DAX cluster can only have one tag with the same key. If you try to add an existing tag (same key), the existing tag value will be updated to the new value.
        public let key: String?
        /// The value of the tag. Tag values are case-sensitive and can be null.
        public let value: String?

        @inlinable
        public init(key: String? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The name of the DAX resource to which tags should be added.
        public let resourceName: String
        /// The tags to be assigned to the DAX resource.
        public let tags: [Tag]

        @inlinable
        public init(resourceName: String, tags: [Tag]) {
            self.resourceName = resourceName
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case resourceName = "ResourceName"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        /// The list of tags that are associated with the DAX resource.
        public let tags: [Tag]?

        @inlinable
        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The name of the DAX resource from which the tags should be removed.
        public let resourceName: String
        /// A list of tag keys. If the DAX cluster has any tags with these keys, then the tags are removed from the cluster.
        public let tagKeys: [String]

        @inlinable
        public init(resourceName: String, tagKeys: [String]) {
            self.resourceName = resourceName
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: String, CodingKey {
            case resourceName = "ResourceName"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        /// The tag keys that have been removed from the cluster.
        public let tags: [Tag]?

        @inlinable
        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct UpdateClusterRequest: AWSEncodableShape {
        /// The name of the DAX cluster to be modified.
        public let clusterName: String
        /// A description of the changes being made to the cluster.
        public let description: String?
        /// The Amazon Resource Name (ARN) that identifies the topic.
        public let notificationTopicArn: String?
        /// The current state of the topic. A value of “active” means that notifications will be sent to the topic. A value of “inactive” means that notifications will not be sent to the topic.
        public let notificationTopicStatus: String?
        /// The name of a parameter group for this cluster.
        public let parameterGroupName: String?
        /// A range of time when maintenance of DAX cluster software will be performed. For example: sun:01:00-sun:09:00. Cluster maintenance normally takes less than 30 minutes, and is performed automatically within the maintenance window.
        public let preferredMaintenanceWindow: String?
        /// A list of user-specified security group IDs to be assigned to each node in the DAX cluster.  If this parameter is not  specified, DAX assigns the default VPC security group to each node.
        public let securityGroupIds: [String]?

        @inlinable
        public init(clusterName: String, description: String? = nil, notificationTopicArn: String? = nil, notificationTopicStatus: String? = nil, parameterGroupName: String? = nil, preferredMaintenanceWindow: String? = nil, securityGroupIds: [String]? = nil) {
            self.clusterName = clusterName
            self.description = description
            self.notificationTopicArn = notificationTopicArn
            self.notificationTopicStatus = notificationTopicStatus
            self.parameterGroupName = parameterGroupName
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.securityGroupIds = securityGroupIds
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case description = "Description"
            case notificationTopicArn = "NotificationTopicArn"
            case notificationTopicStatus = "NotificationTopicStatus"
            case parameterGroupName = "ParameterGroupName"
            case preferredMaintenanceWindow = "PreferredMaintenanceWindow"
            case securityGroupIds = "SecurityGroupIds"
        }
    }

    public struct UpdateClusterResponse: AWSDecodableShape {
        /// A description of the DAX cluster, after it has been modified.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct UpdateParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group.
        public let parameterGroupName: String
        /// An array of name-value pairs for the parameters in the group. Each element in the array represents a single parameter.   record-ttl-millis and query-ttl-millis are the only supported parameter names. For more details, see Configuring TTL Settings.
        public let parameterNameValues: [ParameterNameValue]

        @inlinable
        public init(parameterGroupName: String, parameterNameValues: [ParameterNameValue]) {
            self.parameterGroupName = parameterGroupName
            self.parameterNameValues = parameterNameValues
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
            case parameterNameValues = "ParameterNameValues"
        }
    }

    public struct UpdateParameterGroupResponse: AWSDecodableShape {
        /// The parameter group that has been modified.
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct UpdateSubnetGroupRequest: AWSEncodableShape {
        /// A description of the subnet group.
        public let description: String?
        /// The name of the subnet group.
        public let subnetGroupName: String
        /// A list of subnet IDs in the subnet group.
        public let subnetIds: [String]?

        @inlinable
        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String]? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
        }
    }

    public struct UpdateSubnetGroupResponse: AWSDecodableShape {
        /// The subnet group that has been modified.
        public let subnetGroup: SubnetGroup?

        @inlinable
        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }
}

// MARK: - Errors

/// Error enum for DAX
public struct DAXErrorType: AWSErrorType {
    enum Code: String {
        case clusterAlreadyExistsFault = "ClusterAlreadyExistsFault"
        case clusterNotFoundFault = "ClusterNotFoundFault"
        case clusterQuotaForCustomerExceededFault = "ClusterQuotaForCustomerExceededFault"
        case insufficientClusterCapacityFault = "InsufficientClusterCapacityFault"
        case invalidARNFault = "InvalidARNFault"
        case invalidClusterStateFault = "InvalidClusterStateFault"
        case invalidParameterCombinationException = "InvalidParameterCombinationException"
        case invalidParameterGroupStateFault = "InvalidParameterGroupStateFault"
        case invalidParameterValueException = "InvalidParameterValueException"
        case invalidSubnet = "InvalidSubnet"
        case invalidVPCNetworkStateFault = "InvalidVPCNetworkStateFault"
        case nodeNotFoundFault = "NodeNotFoundFault"
        case nodeQuotaForClusterExceededFault = "NodeQuotaForClusterExceededFault"
        case nodeQuotaForCustomerExceededFault = "NodeQuotaForCustomerExceededFault"
        case parameterGroupAlreadyExistsFault = "ParameterGroupAlreadyExistsFault"
        case parameterGroupNotFoundFault = "ParameterGroupNotFoundFault"
        case parameterGroupQuotaExceededFault = "ParameterGroupQuotaExceededFault"
        case serviceLinkedRoleNotFoundFault = "ServiceLinkedRoleNotFoundFault"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case subnetGroupAlreadyExistsFault = "SubnetGroupAlreadyExistsFault"
        case subnetGroupInUseFault = "SubnetGroupInUseFault"
        case subnetGroupNotFoundFault = "SubnetGroupNotFoundFault"
        case subnetGroupQuotaExceededFault = "SubnetGroupQuotaExceededFault"
        case subnetInUse = "SubnetInUse"
        case subnetQuotaExceededFault = "SubnetQuotaExceededFault"
        case tagNotFoundFault = "TagNotFoundFault"
        case tagQuotaPerResourceExceeded = "TagQuotaPerResourceExceeded"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize DAX
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You already have a DAX cluster with the given identifier.
    public static var clusterAlreadyExistsFault: Self { .init(.clusterAlreadyExistsFault) }
    /// The requested cluster ID does not refer to an existing DAX cluster.
    public static var clusterNotFoundFault: Self { .init(.clusterNotFoundFault) }
    /// You have attempted to exceed the maximum number of DAX clusters for your AWS account.
    public static var clusterQuotaForCustomerExceededFault: Self { .init(.clusterQuotaForCustomerExceededFault) }
    /// There are not enough system resources to create the cluster you requested (or to resize an already-existing cluster).
    public static var insufficientClusterCapacityFault: Self { .init(.insufficientClusterCapacityFault) }
    /// The Amazon Resource Name (ARN) supplied in the request is not valid.
    public static var invalidARNFault: Self { .init(.invalidARNFault) }
    /// The requested DAX cluster is not in the available state.
    public static var invalidClusterStateFault: Self { .init(.invalidClusterStateFault) }
    /// Two or more incompatible parameters were specified.
    public static var invalidParameterCombinationException: Self { .init(.invalidParameterCombinationException) }
    /// One or more parameters in a parameter group are in an invalid state.
    public static var invalidParameterGroupStateFault: Self { .init(.invalidParameterGroupStateFault) }
    /// The value for a parameter is invalid.
    public static var invalidParameterValueException: Self { .init(.invalidParameterValueException) }
    /// An invalid subnet identifier was specified.
    public static var invalidSubnet: Self { .init(.invalidSubnet) }
    /// The VPC network is in an invalid state.
    public static var invalidVPCNetworkStateFault: Self { .init(.invalidVPCNetworkStateFault) }
    /// None of the nodes in the cluster have the given node ID.
    public static var nodeNotFoundFault: Self { .init(.nodeNotFoundFault) }
    /// You have attempted to exceed the maximum number of nodes for a DAX cluster.
    public static var nodeQuotaForClusterExceededFault: Self { .init(.nodeQuotaForClusterExceededFault) }
    /// You have attempted to exceed the maximum number of nodes for your AWS account.
    public static var nodeQuotaForCustomerExceededFault: Self { .init(.nodeQuotaForCustomerExceededFault) }
    /// The specified parameter group already exists.
    public static var parameterGroupAlreadyExistsFault: Self { .init(.parameterGroupAlreadyExistsFault) }
    /// The specified parameter group does not exist.
    public static var parameterGroupNotFoundFault: Self { .init(.parameterGroupNotFoundFault) }
    /// You have attempted to exceed the maximum number of parameter groups.
    public static var parameterGroupQuotaExceededFault: Self { .init(.parameterGroupQuotaExceededFault) }
    /// The specified service linked role (SLR) was not found.
    public static var serviceLinkedRoleNotFoundFault: Self { .init(.serviceLinkedRoleNotFoundFault) }
    /// You have reached the maximum number of x509 certificates that can be created for encrypted clusters in a 30 day period. Contact AWS customer support to discuss options for continuing to create encrypted clusters.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The specified subnet group already exists.
    public static var subnetGroupAlreadyExistsFault: Self { .init(.subnetGroupAlreadyExistsFault) }
    /// The specified subnet group is currently in use.
    public static var subnetGroupInUseFault: Self { .init(.subnetGroupInUseFault) }
    /// The requested subnet group name does not refer to an existing subnet group.
    public static var subnetGroupNotFoundFault: Self { .init(.subnetGroupNotFoundFault) }
    /// The request cannot be processed because it would exceed the allowed number of subnets in a subnet group.
    public static var subnetGroupQuotaExceededFault: Self { .init(.subnetGroupQuotaExceededFault) }
    /// The requested subnet is being used by another subnet group.
    public static var subnetInUse: Self { .init(.subnetInUse) }
    /// The request cannot be processed because it would exceed the allowed number of subnets in a subnet group.
    public static var subnetQuotaExceededFault: Self { .init(.subnetQuotaExceededFault) }
    /// The tag does not exist.
    public static var tagNotFoundFault: Self { .init(.tagNotFoundFault) }
    /// You have exceeded the maximum number of tags for this DAX cluster.
    public static var tagQuotaPerResourceExceeded: Self { .init(.tagQuotaPerResourceExceeded) }
}

extension DAXErrorType: Equatable {
    public static func == (lhs: DAXErrorType, rhs: DAXErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension DAXErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
